package functionality;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import entity.DALException;
import entity.IOperatoerDTO;
import entity.OperatoerDTO;

public class OperatoerDAO implements IOperatoerDAO {

	private int oprID=11;
	List<IOperatoerDTO> oprList = new ArrayList<IOperatoerDTO>();
	List<IOperatoerDTO> delOpr = new ArrayList<IOperatoerDTO>();

	@Override
	public IOperatoerDTO getOperatoer(int oprId) throws DALException {
		IOperatoerDTO output=null;
		for(int i=0;i<oprList.size();i++){
			if(oprList.get(i).getOprId()==oprId){
				output=oprList.get(i);
			}
		}
		return output;
	}

	@Override
	public List<IOperatoerDTO> getOperatoerList() throws DALException {
		return oprList;
	}

	public List<IOperatoerDTO> getDelOpr(){
		return delOpr;
	}

	@Override
	public String createOperatoer(String forName, String efterName, String cpr) throws DALException {
		String ini = createInitial(forName, efterName);
		String password = passwordGen();
		int oprId=oprID;
		oprList.add(new OperatoerDTO(forName, efterName, cpr, ini, oprId, password, true));
		oprID++;
		int currentOprID = oprID -1;
		return "Operatoer ID: " + currentOprID + "\t Password: " + password;
	}

	@Override
	public String updateOperatoer(int oprID, String forName, String lastName) throws DALException {
		String ini = "Operatør ej fundet.";
		for(int i=0;i<oprList.size();i++){ 
			if(oprID==oprList.get(i).getOprId()){
				ini = createInitial(forName, lastName);
				oprList.get(i).setIni(ini);
				oprList.get(i).setName(forName, lastName);
			}
		}
		return ini;
	}

	public boolean deleteOperatoer(int oprID){
		boolean output = false;
		for (int i=0; i<oprList.size(); i++){
			if(oprID==oprList.get(i).getOprId()){
				delOpr.add(oprList.get(i));
				oprList.remove(i);
				output = true;
			}
		}
		return output;
	}

	public String passwordGen(){
		// Tegn der kan indgå i passwordet
		String low = "abcdefghijklmnopqrstuvwxyz";
		String up = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
		String num = "0123456789";
		String special = ".-_+!?=";

		int lowCount = 0, upCount = 0, numCount = 0, specialCount = 0; // Antal tegn af typen der indgår i passwordet
		String password = "";

		Random r = new Random(); // Random objekt bruges til at generere tilfældige tal
		int pLength = r.nextInt(5) + 6; // Længden på passwordet (0-5 + 6)

		for (int i=0; i<pLength ;i++){
			int p; // Tal mellem 0-3 som indikerer hvilken type tegn det næste tegn i password skal være.

			// Hvis der stadig er mindst 2 pladser tilbage i password er det ligegyldigt..
			// ... hvilken type tegn der vælges
			if (i < pLength - 2){ 
				p = r.nextInt(4); // 0-3	
			} else if (lowCount < 1){ // Ellers tjekkes der om vi har mindst en forekomst af typerne
				p = 0;
			} else if (upCount < 1){
				p = 1;
			} else if (numCount < 1){
				p = 2;
			} else if (specialCount < 1){
				p = 3;
			} else { // Hvis der er mindst en forekomst af alle typer vælges en tilfældig
				p = r.nextInt(4);
			}
			switch (p){
			case 0:{
				password += low.charAt(r.nextInt(low.length())); // Vælg random tegn og tilføj til password
				lowCount++; // Indikerer at password indeholder et lower case bogstav
			}
			break;
			case 1:{
				password += up.charAt(r.nextInt(up.length()));	
				upCount++;
			}
			break;
			case 2:{
				password += num.charAt(r.nextInt(num.length()));
				numCount++;
			}
			break;
			case 3:{
				password += special.charAt(r.nextInt(special.length())); 
				specialCount++;
			}
			break;
			}
		}	
		return password;
	}

	public boolean passwordChange(int ID, String password, String newPassword){
		boolean output = false;
		for(int i=0;i<oprList.size();i++){ 
			if(ID==oprList.get(i).getOprId() && password.equals(oprList.get(i).getPassword())){
				if(checkPassword(newPassword)){ 
					oprList.get(i).setPassword(newPassword); 
					output = true;
				}
			}
		}
		return output;
	}

	public String createInitial(String fornavn, String efternavn){
		Random r = new Random();
		int posF = r.nextInt(fornavn.length()-1) + 1;
		int posL = r.nextInt(efternavn.length()-1) + 1;
		String output = new String(new char[]{ fornavn.toUpperCase().charAt(0), fornavn.toLowerCase().charAt(posF), efternavn.toUpperCase().charAt(0), efternavn.toLowerCase().charAt(posL)});
		if (oprList.size() > 0){
			for(IOperatoerDTO i : oprList){
				if(output.equals(i.getIni())){
					output=newInit(output);
				}
			}
		}
		return output;
	}

	private String newInit(String current){
		Random r = new Random();
		String low = "abcdefghijklmnopqrstuvwxyz";
		String output = new String(new char[]{current.charAt(0),current.charAt(1),current.charAt(2),low.charAt(r.nextInt(26))});
		for(IOperatoerDTO i : oprList){
			if(output.equals(i.getIni())){
				output=newInit(output);
			}
		}
		return output;
	}

	public boolean checkPassword(String newPassword){
		boolean output = false;
		boolean lowCount=false, upCount=false, numCount=false, specialCount=false;
		String low = "abcdefghijklmnopqrstuvwxyz";
		String up = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
		String num = "0123456789";
		String special = ".-_+!?=";
		if(newPassword.length()>=6 && newPassword.length()<=20){
			for(int i=0;i<low.length();i++){
				String l = Character.toString(low.charAt(i));
				if(newPassword.contains(l)){
					lowCount=true;
				}
			}
			for(int i=0;i<up.length();i++){
				String u = Character.toString(up.charAt(i));
				if(newPassword.contains(u)){
					upCount=true;
				}
			}
			for(int i=0;i<num.length();i++){
				String n = Character.toString(num.charAt(i));
				if (newPassword.contains(n)){
					numCount=true;
				}
			}
			for(int i=0;i<special.length();i++){
				String s = Character.toString(special.charAt(i));
				if (newPassword.contains(s)){
					specialCount=true;
				}
			}
			int p=0;
			if(lowCount==true){
				p++;
			}
			if(upCount==true){
				p++;
			}
			if(numCount==true){
				p++;
			}
			if(specialCount==true){
				p++;		
			}

			if(p>=3){
				output=true;
			}else{
				output=false;
			}
		}
		return output;
	}

	@Override
	public String resetPassword(int oprID) {
		String newPassword = passwordGen();
		for(int i=0;i<oprList.size();i++){ 
			if(oprID==oprList.get(i).getOprId()){
				oprList.get(i).setPassword(newPassword); //setPassword metode findes ikke
			}
		}
		return newPassword;
	}
}
